﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Xml.Linq;
using MaQiu.SqlExecute.DAL;

namespace MLogHelper.Business
{
    internal class Configurer
    {
        internal class LoggerConfig
        {
            public string LoggerName { set; get; }
            public string Remarks { set; get; }
            public bool IsOpen { set; get; }
        }
        internal class TriggerConfig
        {
            public string Table { set; get; }
            public string Field { set; get; }
            public string Remarks { set; get; }
        }

        internal class TriggerDetail
        {
            public string TriggerName { set; get; }
            public string TableName { set; get; }
            public int IsDisabled { set; get; }
            public string TriggerType { set; get; }
            public string TriggerContent { set; get; }
            public string CreatedDate { set; get; }
            public string Remarks { set; get; }
        }
        internal class AutoCompleteValue
        {
            public string value { set; get; }
        }

        public class MyLogX
        {
            public Guid LogXId { set; get; }
            public string Date { set; get; }
            public string Thread { set; get; }
            public string Level { set; get; }
            public string Logger { set; get; }
            public string Message { set; get; }
            public string Exception { set; get; }
            public string TraceStack { set; get; }
            public string Url { set; get; }
            public string UrlRefer { set; get; }
            public string Cookie { set; get; }
            public string Session { set; get; }
        }

        public class MyLogXTriggerChgLog
        {
            public Guid MyLogXTriggerChgLogGUID { set; get; }
            public Guid KeyGUID { set; get; }
            public string LogDate { set; get; }
            public string LogSource { set; get; }
            public string ExecSql { set; get; }
            public string ChgType { set; get; }
            public string ChgTable { set; get; }
            public string ChgField { set; get; }
            public string BeforeInfo { set; get; }
            public string AfterInfo { set; get; }
        }

        public class MyTextLog
        {
            public string FileName { set; get; }
            public string Abstract { set; get; }
        }

        internal class SearchRecentConfig
        {
            public int PageSize { set; get; }
            public int PageCurrent { set; get; }
            public Dictionary<string, string> SearchText { set; get; }
        }

        internal class SearchTextConfig
        {
            public string DateBgn { set; get; }
            public string SearchText { set; get; }
        }

        internal class SearchRecentResult
        {
            public int DataCount { set; get; }
            public List<MyLogX> LogList { set; get; }
        }
        internal class SearchTriggerLogResult
        {
            public int DataCount { set; get; }
            public List<MyLogXTriggerChgLog> LogList { set; get; }
        }

        public bool TryLogin(string code, string pwd)
        {
            bool success = SqlQuery.Create(@"select 1 from MyLogXUserAccount where UserCode=@UserCode and UserPwd=@UserPwd", new { UserCode = code, UserPwd = pwd }).ExecuteScalar<int>() == 1;
            return success;
        }

        public List<LoggerConfig> GetAllLogger()
        {
            var xml = XElement.Parse(GetConfigFileContent());
            var list = xml.Descendants("logger").Select(i => new LoggerConfig() { LoggerName = i.Attribute("name").Value, Remarks = i.Attribute("remarks")?.Value, IsOpen = i.Element("level").Attribute("value").Value == "ALL" });
            return list.ToList();
        }

        public List<TriggerDetail> GetAllTrigger()
        {
            var list = SqlQuery.Create(@"SELECT   triggers.name AS TriggerName,
                                                    tables.name AS TableName,
                                                    triggers.is_disabled AS IsDisabled,
                                                    CASE
                                                        WHEN triggers.is_instead_of_trigger = 1 THEN
                                                            'INSTEAD OF'
                                                        WHEN triggers.is_instead_of_trigger = 0 THEN
                                                            'AFTER'
                                                        ELSE
                                                            NULL
                                                    END AS TriggerType,
                                                    c.definition TriggerContent,
                                                    triggers.create_date CreatedDate,
		                                            d.Remarks
                                        FROM     sys.triggers triggers
                                                    INNER JOIN sys.tables tables ON triggers.parent_id = tables.object_id
                                                                                    AND triggers.type = 'TR'
                                                    INNER JOIN sys.syscomments com ON triggers.object_id = com.id
                                                                                    AND com.text LIKE '%DBCC INPUTBUFFER(@@spid) WITH NO_INFOMSGS%'
                                                    INNER JOIN sys.sql_modules c ON triggers.object_id = c.object_id
                                                    LEFT JOIN MyLogXTrigger d ON triggers.name = d.TriggerName
                                        ORDER BY triggers.create_date desc;").ToList<TriggerDetail>();
            return list;
        }

        internal SearchTriggerLogResult GetTriggerLog(SearchRecentConfig config)
        {
            SearchTriggerLogResult result = new SearchTriggerLogResult();
            List<string> whereSql = new List<string>();
            List<DbParameter> pList = new List<DbParameter>();
            List<DbParameter> pList1 = new List<DbParameter>();
            var minDate = "1900-01-01";
            var maxDate = DateTime.MaxValue.ToString("yyyy-MM-dd");
            int i = 0;
            foreach (var item in config.SearchText)
            {
                if (!string.IsNullOrEmpty(item.Value))
                {
                    if (item.Key.Contains("Date"))
                    {
                        whereSql.Add(item.Key.Contains("Begin")
                            ? $"([LogDate] BETWEEN @value{i.ToString()} AND '{maxDate}')"
                            : $"([LogDate] BETWEEN '{minDate}' AND @value{i.ToString()})");

                        var value = item.Value;
                        if (item.Key == "DateEnd")
                        {
                            value = item.Value + " 23:59:59";
                        }

                        pList.Add(new SqlParameter($"@value{i.ToString()}", value));
                        pList1.Add(new SqlParameter($"@value{i.ToString()}", value));
                        i++;
                    }
                    else
                    {
                        whereSql.Add($"([{item.Key}] LIKE '%' + @value{i.ToString()} + '%')");
                        pList.Add(new SqlParameter($"@value{i.ToString()}", item.Value));
                        pList1.Add(new SqlParameter($"@value{i.ToString()}", item.Value));
                        i++;
                    }
                }
            }
            string sql = @"
            SELECT {0}
            FROM   MyLogXTriggerChgLog a WITH (NOLOCK)
            WHERE  " + (!whereSql.Any() ? "(1=1)" : string.Join(" AND ", whereSql.ToArray()));
            result.DataCount = SqlQuery.Create(string.Format(sql, "COUNT(1)", ""), pList).ExecuteScalar<int>();
            result.LogList = SqlQuery.Create(string.Format($"SELECT TOP {config.PageSize} * FROM ({sql}) t WHERE t.Id BETWEEN {((config.PageCurrent - 1) * config.PageSize) + 1} AND {config.PageCurrent * config.PageSize} ORDER BY t.[LogDate] DESC",
                "ROW_NUMBER() OVER (ORDER BY a.[LogDate] DESC) Id, MyLogXTriggerChgLogGUID,KeyGUID,LogDate,LogSource,ExecSql,ChgType,ChgField,ChgTable,BeforeInfo,AfterInfo"), pList1).ToList<MyLogXTriggerChgLog>();
            return result;
        }

        public void DeleteTrigger(TriggerDetail triggerDetail)
        {
            if (!triggerDetail.TriggerName.StartsWith("tr_AutoMonitor_"))
            {
                throw new ArgumentException("不允许删除非自动生成的触发器；");
            }
            SqlQuery.Create($@"DELETE FROM dbo.MyLogXTrigger WHERE TriggerName = @TriggerName;
                              DROP TRIGGER [{triggerDetail.TriggerName}];", new { TriggerName = triggerDetail.TriggerName }).ExecuteNonQuery();
        }

        public void UpdateTrigger(TriggerDetail trigger)
        {
            SqlQuery.Create($@"IF NOT EXISTS (   SELECT TOP 1
                                                         1
                                                  FROM   MyLogXTrigger
                                                  WHERE  TriggerName = @TriggerName )
                                    BEGIN
                                        INSERT INTO MyLogXTrigger ( MyLogXTriggerGUID,
                                                                    TriggerName,
                                                                    Remarks,
                                                                    AddDateTime )
                                        VALUES ( @MyLogXTriggerGUID, @TriggerName, @Remarks, GETDATE());
                                    END;
                                ELSE
                                    BEGIN
                                        UPDATE MyLogXTrigger
                                        SET    Remarks = @Remarks
                                        WHERE  TriggerName = @TriggerName;
                                    END;", new { MyLogXTriggerGUID = Guid.NewGuid(), TriggerName = trigger.TriggerName, Remarks = trigger.Remarks }).ExecuteNonQuery();
        }

        public void AddTrigger(TriggerConfig triggerConfig)
        {
            using (var scope = new MaQiu.SqlExecute.DAL.SqlConnection())
            {
                var list = GetAllTrigger();
                var key = SqlQuery.Create(@"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME=@name", new { name = triggerConfig.Table }).ExecuteScalar<string>();
                if (string.IsNullOrEmpty(key))
                {
                    throw new ArgumentException("该表没有主键，无法创建触发器；");
                }
                if (SqlQuery.Create(@"SELECT TOP 1 1 FROM sys.syscolumns WHERE name=@name AND id = OBJECT_ID(@table)", new { name = triggerConfig.Field, table = triggerConfig.Table }).ExecuteScalar<int>() != 1)
                {
                    throw new ArgumentException("不存在这个字段；");
                }
                if (list.Where(i => i.TriggerContent.ToLower().Contains($@"UPDATE({triggerConfig.Field})".ToLower()) && i.TriggerContent.ToLower().Contains(triggerConfig.Table.ToLower())).Any())
                {
                    throw new ArgumentException("疑似已经存在这个字段的监控，请自行手动添加；");
                }
                if (list.Count >= 20)
                {
                    throw new ArgumentException("监控触发器过多，请去后台删除一部分；");
                }
                var triggerName = $@"tr_AutoMonitor_{triggerConfig.Table}_{triggerConfig.Field}";
                SqlQuery.Create($@"CREATE TRIGGER {triggerName}
                                ON [{triggerConfig.Table}]
                                AFTER INSERT, UPDATE, DELETE
                                AS
                                    BEGIN TRY
                                        IF UPDATE({triggerConfig.Field})
                                           OR NOT EXISTS (   SELECT TOP 1
                                                                    1
                                                             FROM   Inserted )
                                            BEGIN
                                                DECLARE @INSERTUPDATE NVARCHAR(30),
                                                        @LASTCOMMAND NVARCHAR(MAX);

                                                DECLARE @SQLBuffer NVARCHAR(4000);

                                                DECLARE @buffer TABLE ( EventType NVARCHAR(30),
                                                                        Parameters INT,
                                                                        EventInfo NVARCHAR(4000));
                                                INSERT @buffer
                                                EXEC sp_executesql N'DBCC INPUTBUFFER(@@spid) WITH NO_INFOMSGS';

                                                SELECT @LASTCOMMAND = EventInfo
                                                FROM   @buffer;

                                                DECLARE @_AppName_ VARCHAR(100);
                                                SET @_AppName_ = (   SELECT program_name
                                                                     FROM   sys.dm_exec_sessions
                                                                     WHERE  session_id = @@SPID );
                                                IF EXISTS (   SELECT 1
                                                              FROM   inserted )
                                                    BEGIN
                                                        INSERT INTO MyLogXTriggerChgLog ( MyLogXTriggerChgLogGUID,
                                                                                          KeyGUID,
                                                                                          LogDate,
                                                                                          LogSource,
                                                                                          ExecSql,
                                                                                          ChgType,
														                                  ChgTable,
                                                                                          ChgField,
                                                                                          BeforeInfo,
                                                                                          AfterInfo )
                                                        SELECT NEWID(),
                                                               a.[{key}],
                                                               GETDATE(),
                                                               @_AppName_,
                                                               @LASTCOMMAND,
                                                               CASE
                                                                   WHEN EXISTS (   SELECT 1
                                                                                   FROM   deleted ) THEN
                                                                       'UPDATE'
                                                                   ELSE
                                                                       'INSERT'
                                                               END,
                                                               '{triggerConfig.Table}',
                                                               '{triggerConfig.Field}',
                                                               b.[{triggerConfig.Field}],
                                                               a.[{triggerConfig.Field}]
                                                        FROM   Inserted a
                                                               LEFT JOIN Deleted b ON a.[{key}] = b.[{key}];
                                                    END;
                                                ELSE
                                                    BEGIN
                                                        INSERT INTO MyLogXTriggerChgLog ( MyLogXTriggerChgLogGUID,
                                                                                          KeyGUID,
                                                                                          LogDate,
                                                                                          LogSource,
                                                                                          ExecSql,
                                                                                          ChgType,
														                                  ChgTable,
                                                                                          ChgField,
                                                                                          BeforeInfo,
                                                                                          AfterInfo )
                                                        SELECT NEWID(),
                                                               b.[{key}],
                                                               GETDATE(),
                                                               @_AppName_,
                                                               @LASTCOMMAND,
                                                               'DELETE',
                                                               '{triggerConfig.Table}',
                                                               '{triggerConfig.Field}',
                                                               b.{triggerConfig.Field},
                                                               NULL
                                                        FROM   Deleted b;
                                                    END;

                                            END;
                                    END TRY
                                    BEGIN CATCH
                                    END CATCH;").ExecuteNonQuery();

                SqlQuery.Create($@"DELETE FROM dbo.MyLogXTrigger WHERE TriggerName = @TriggerName
                                INSERT INTO dbo.MyLogXTrigger ( MyLogXTriggerGUID,
                                                                TriggerName,
                                                                Remarks,
                                                                AddDateTime )
                                VALUES ( @MyLogXTriggerGUID,     
                                         @TriggerName,      
                                         @Remarks,      
                                         GETDATE() )", new { MyLogXTriggerGUID = Guid.NewGuid(), TriggerName = triggerName, Remarks = triggerConfig.Remarks }).ExecuteNonQuery();
            }
        }

        public List<AutoCompleteValue> SearchField(string v1, string v2)
        {
            return SqlQuery.Create(@"SELECT DISTINCT name value FROM sys.syscolumns WHERE id = OBJECT_ID(@name) AND name LIKE '%' + @field + '%'", new { name = v1, field = v2 }).ToList<AutoCompleteValue>();
        }

        public List<AutoCompleteValue> SearchTable(string v)
        {
            return SqlQuery.Create(@"SELECT DISTINCT name value FROM sys.sysobjects WHERE type='U' AND name LIKE '%' + @name + '%'", new { name = v }).ToList<AutoCompleteValue>();
        }

        public void SetLoggerStatus(string name, bool isOpen)
        {
            var xml = XElement.Parse(GetConfigFileContent());
            var nodes = xml.Descendants("logger").Where(i => i.Attribute("name").Value == name);
            if (nodes.Count() == 0) return;
            var node = nodes.First();
            var levelValue = node.Element("level").Attribute("value");
            bool oldValue = levelValue.Value == "ALL";
            if (isOpen == oldValue) return;
            if (isOpen) levelValue.Value = "ALL";
            else levelValue.Value = "OFF";
            SaveConfigFile(xml.ToString());
            SyncConfigToDB(node);
        }

        public void SetTriggerStatus(string name, string tableName, bool isOpen)
        {
            var list = GetAllTrigger();
            if (!list.Select(i => i.TriggerName).Contains(name) || !list.Select(i => i.TableName).Contains(tableName))
            {
                throw new ArgumentException("非法请求");
            }
            if (isOpen)
            {
                SqlQuery.Create($@"ENABLE TRIGGER {name} ON {tableName}").ExecuteNonQuery();
            }
            else
            {
                SqlQuery.Create($@"DISABLE TRIGGER {name} ON {tableName}").ExecuteNonQuery();
            }
        }

        public void EditLogger(LoggerConfig log)
        {
            var xml = XElement.Parse(GetConfigFileContent());
            var nodes = xml.Descendants("logger").Where(i => i.Attribute("name").Value == log.LoggerName);
            if (nodes.Count() == 0) throw new ArgumentException("不存在的日志类型！");
            var node = nodes.First();
            node.SetAttributeValue("remarks", log.Remarks);
            SaveConfigFile(xml.ToString());
            SyncConfigToDB(node);
        }

        public void AddLogger(LoggerConfig log)
        {
            var xml = XElement.Parse(GetConfigFileContent());
            var node = xml.Descendants("logger").Where(i => i.Attribute("name").Value == log.LoggerName);
            if (node.Count() > 0) throw new ArgumentException("名称重复,禁止新增！");
            var nodeDefault = new XElement(xml.Descendants("logger").Where(i => i.Attribute("name").Value == "常规运行日志").First());
            nodeDefault.Attribute("name").Value = log.LoggerName;
            xml.Descendants("log4net").First().Add(nodeDefault);
            nodeDefault.SetAttributeValue("remarks", log.Remarks);
            SaveConfigFile(xml.ToString());
            SyncConfigToDB(nodeDefault);
        }

        public void DelLogger(string name)
        {
            if (name == "默认日志" || name == "常规运行日志") throw new ArgumentException("禁止删除系统记录器！");
            var xml = XElement.Parse(GetConfigFileContent());
            var node = xml.Descendants("logger").Where(i => i.Attribute("name").Value == name);
            if (node.Count() == 0) return;
            node.Remove();
            SaveConfigFile(xml.ToString());
            DeleteConfigFromDB(name);
        }

        public Dictionary<string, string> GetLogReserveInfo()
        {
            var xml = XElement.Parse(GetConfigFileContent());
            var node = xml.Descendants("appender").Where(i => i.Attribute("name").Value == "常规文件记录器");
            var maxSizeRollBackups = node.Descendants("param").Where(i => i.Attribute("name").Value == "MaxSizeRollBackups").First().Attribute("value").Value;
            var maximumFileSize = node.Descendants("param").Where(i => i.Attribute("name").Value == "MaximumFileSize").First().Attribute("value").Value;
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("MaxSizeRollBackups", maxSizeRollBackups);
            dic.Add("MaximumFileSize", maximumFileSize);
            return dic;
        }

        public void SetLogReserveInfo(Dictionary<string, string> dic)
        {
            var oldXml = GetConfigFileContent();
            var xml = XElement.Parse(oldXml);
            var node = xml.Descendants("appender").Where(i => i.Attribute("name").Value == "常规文件记录器");
            var maxSizeRollBackups = node.Descendants("param").Where(i => i.Attribute("name").Value == "MaxSizeRollBackups").First().Attribute("value");
            var maximumFileSize = node.Descendants("param").Where(i => i.Attribute("name").Value == "MaximumFileSize").First().Attribute("value");
            if (dic["MaxSizeRollBackups"] != null)
                maxSizeRollBackups.Value = dic["MaxSizeRollBackups"];
            if (dic["MaximumFileSize"] != null)
                maximumFileSize.Value = dic["MaximumFileSize"];
            if (oldXml != xml.ToString())
                SaveConfigFile(xml.ToString());
        }

        public List<MyTextLog> GetCommonLogFiles()
        {
            var dir = StaticInit.LogDir;
            return new DirectoryInfo(dir).GetFiles("Mlog_*.txt").Select(i => new MyTextLog() { FileName = i.Name }).OrderByDescending(i => i.FileName).ToList();
        }

        public List<MyTextLog> GetSimpleLogFiles()
        {
            var dir = StaticInit.LogDir;
            return new DirectoryInfo(dir).GetFiles("all_*.txt").Select(i => new MyTextLog() { FileName = i.Name }).OrderByDescending(i => i.FileName).ToList();
        }

        public List<MyTextLog> SearchTextInLog(SearchTextConfig config, bool isSimple)
        {
            var dir = new DirectoryInfo(StaticInit.LogDir);
            var result = new List<MyTextLog>();
            if (string.IsNullOrEmpty(config.DateBgn) && !string.IsNullOrEmpty(config.SearchText))
            {
                throw new ArgumentException("必须输入一个日期才能搜索!");
            }
            if (!string.IsNullOrEmpty(config.DateBgn) && string.IsNullOrEmpty(config.SearchText))
            {
                throw new ArgumentException("请配合搜索内容查询!");
            }
            if (!DateTime.TryParse(config.DateBgn, out var bgn) || string.IsNullOrEmpty(config.SearchText))
                return isSimple ? GetSimpleLogFiles() : GetCommonLogFiles();

            for (var i = 0; i < 11; i++)
            {
                string preFix = "Mlog";
                var dString = bgn.AddDays(i).ToString("yyyyMMdd");
                if (isSimple) { preFix = "all"; }
                var files = dir.GetFiles(preFix + "_" + dString + "*");
                if (!files.Any()) continue;
                foreach (var file in files)
                {
                    int count = 0;
                    using (var fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        using (var sr = new StreamReader(fs, Encoding.UTF8))
                        {
                            string line;
                            while ((line = sr.ReadLine()) != null)
                            {
                                count++;
                                if (line.IndexOf(config.SearchText, StringComparison.CurrentCulture) == -1) continue;
                                result.Add(new MyTextLog() { FileName = file.Name, Abstract = $"第{count.ToString()}行,内容为: " + line });
                                break;
                            }
                        }
                    }
                }
            }
            return result.OrderByDescending(i => i.FileName).ToList();
        }

        public SearchRecentResult GetRecentLog(SearchRecentConfig config)
        {
            SearchRecentResult result = new SearchRecentResult();
            List<string> whereSql = new List<string>();
            List<DbParameter> pList = new List<DbParameter>();
            List<DbParameter> pList1 = new List<DbParameter>();
            var minDate = "1900-01-01";
            var maxDate = DateTime.MaxValue.ToString("yyyy-MM-dd");
            int i = 0;
            foreach (var item in config.SearchText)
            {
                if (!string.IsNullOrEmpty(item.Value))
                {
                    if (item.Key.Contains("Date"))
                    {
                        whereSql.Add(item.Key.Contains("Begin")
                            ? $"([Date] BETWEEN @value{i.ToString()} AND '{maxDate}')"
                            : $"([Date] BETWEEN '{minDate}' AND @value{i.ToString()})");

                        var value = item.Value;
                        value = DateTime.Parse(value).ToString("yyyy-MM-dd");

                        pList.Add(new SqlParameter($"@value{i.ToString()}", value));
                        pList1.Add(new SqlParameter($"@value{i.ToString()}", value));
                        i++;
                    }
                    else
                    {
                        whereSql.Add($"([{item.Key}] LIKE '%' + @value{i.ToString()} + '%')");
                        pList.Add(new SqlParameter($"@value{i.ToString()}", item.Value));
                        pList1.Add(new SqlParameter($"@value{i.ToString()}", item.Value));
                        i++;
                    }
                }
            }
            string sql = @"
            SELECT {0}
            FROM   MyLogX a WITH (NOLOCK)
            WHERE  " + (!whereSql.Any() ? "(1=1)" : string.Join(" AND ", whereSql.ToArray()));
            result.DataCount = SqlQuery.Create(string.Format(sql, "COUNT(1)", ""), pList).ExecuteScalar<int>();
            result.LogList = SqlQuery.Create(string.Format($"SELECT TOP {config.PageSize} * FROM ({sql}) t WHERE t.Id BETWEEN {((config.PageCurrent - 1) * config.PageSize) + 1} AND {config.PageCurrent * config.PageSize} ORDER BY t.[Date] DESC",
                "ROW_NUMBER() OVER (ORDER BY a.[Date] DESC) Id, LogXId, Date, Thread, Level, Logger, Message, Exception, TraceStack, Url, UrlRefer, Cookie, Session"), pList1).ToList<MyLogX>();
            return result;
        }

        private void SyncConfigToDB(XElement node)
        {
            var loggerName = node.Attribute("name").Value;
            var remarks = node.Attribute("remarks") == null ? "" : node.Attribute("remarks").Value;
            var isOpen = node.Element("level").Attribute("value").Value == "ALL" ? 1 : 0;
            SqlQuery.Create(@"DELETE FROM MyLogXLogger WHERE LoggerName = @LoggerName
                            INSERT INTO MyLogXLogger(MyLogXLoggerGUID, LoggerName, Remarks, IsOpen)
                            VALUES(NEWID(), @LoggerName, @Remarks, @IsOpen)",
                            new
                            {
                                LoggerName = loggerName,
                                Remarks = remarks,
                                IsOpen = isOpen
                            }).ExecuteNonQuery();
        }

        private void DeleteConfigFromDB(string name)
        {
            SqlQuery.Create(@"DELETE FROM MyLogXLogger WHERE LoggerName = @LoggerName",
                            new
                            {
                                LoggerName = name
                            }).ExecuteNonQuery();
        }

        public static string GetConfigFileContent()
        {
            lock (StaticInit.Lock)
            {
                using (var fs = new FileStream(StaticInit.ConfigFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (var sr = new StreamReader(fs, Encoding.UTF8))
                    {
                        string line = sr.ReadToEnd();
                        return line;
                    }
                }
            }
        }

        public static void SaveConfigFile(string xml)
        {
            lock (StaticInit.Lock)
            {
                try
                {
                    File.WriteAllText(StaticInit.ConfigFile, xml);
                }
                catch (IOException)
                {
                    Thread.Sleep(1000);
                    File.WriteAllText(StaticInit.ConfigFile, xml);
                }
            }
        }

    }
}
